import codecs
import heapq
import tkinter
from tkinter import NE
from adjustment_curve import get_the_route
import numpy as np
from PIL import ImageTk,Image
from geatpy import bs2ri, crtpc, mutbin, ranking, selecting
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk #NavigationToolbar2TkAgg
import config
from calculate_bias import Bias



def Readfile1(address):
    f = codecs.open(address, mode='r', encoding='utf-8')
    line = f.readline()  # 以行的形式进行读取文件
    x = []
    y = []
    r = []
    len1 = []
    len2 = []
    while line:
        a = line.split()
        b = a[0:1]
        y.append(float(b[0]))
        b = a[1:2]
        x.append(float(b[0]))
        b = a[2:3]
        r.append(float(b[0]))
        b = a[3:4]
        len1.append(float(b[0]))
        b = a[4:5]
        len2.append(float(b[0]))
        line = f.readline()
    f.close()
    return x, y, r, len1, len2


def Readfile2(address):
    f = codecs.open(address, mode='r', encoding='utf-8')
    line = f.readline()  # 以行的形式进行读取文件
    x = []
    y = []
    r = []
    while line:
        a = line.split()
        b = a[0:1]
        x.append(float(b[0]))
        b = a[1:2]
        y.append(float(b[0]))
        b = a[2:3]
        r.append(float(b[0]))
        line = f.readline()
    f.close()
    return x, y, r


x1, y1, r1, front, behind = Readfile1(config.line_value_file_path)
x2, y2, r2 = Readfile2(config.section_value_path)

bi = Bias()

ori = x1 + y1 + r1 + front + behind + x2 + y2 + r2
index_num = len(ori)
def cal_ori():
    bi.dod.update_curves(x1, y1, r1, front, behind, x2, y2, r2)
    return bi.cal_bias(None, -1500, -1450)
t_x1 = []
t_x1.append(x1[17])
t_x1.append(x1[18])
t_x1.append(x1[19])
t_y1 = []
t_y1.append(y1[17])
t_y1.append(y1[18])
t_y1.append(y1[19])
t_r1 = []
t_r1.append(r1[17])
t_r1.append(r1[18])
t_r1.append(r1[19])
t_front = []
t_front.append(front[17])
t_front.append(front[18])
t_front.append(front[19])
t_behind = []
t_behind.append(behind[17])
t_behind.append(behind[18])
t_behind.append(behind[19])
t_x2 = []
t_x2.append(x2[28])
t_x2.append(x2[29])
t_x2.append(x2[30])
t_y2 = []
t_y2.append(y2[28])
t_y2.append(y2[29])
t_y2.append(y2[30])
t_r2 = []
t_r2.append(r2[28])
t_r2.append(r2[29])
t_r2.append(r2[30])

x1_range = 0.2
y1_range = 0.2
r1_range = 5
front_range = 5
behind_range = 5
x2_range = 0.2
y2_range = 0.2
r2_range = 5

the_lb = [-x1_range] * len(t_x1) + [-y1_range] * len(t_y1) + [-r1_range] * len(t_r1) + [-front_range] * len(t_front) + [
    -behind_range] * len(t_behind) + [-x2_range] * len(t_x2) + [-y2_range] * len(t_y2) + [-r2_range] * len(t_r2)
the_ub = [x1_range] * len(t_x1) + [y1_range] * len(t_y1) + [r1_range] * len(t_r1) + [front_range] * len(t_front) + [
    behind_range] * len(t_behind) + [x2_range] * len(t_x2) + [y2_range] * len(t_y2) + [r2_range] * len(t_r2)

len_autosome = []  # 每个决策变量用二进制编码的长度
method = []  # 决策变量编码方式
log_method = []  # 决策变量是否使用对数刻度
ld_include = []  # 各决策变量的范围是否包含下界
ud_include = []  # 各决策变量的范围是否包含上界
index_type = []  # 表示决策变量的类型
for i in range(0, 24):
    len_autosome.append(10)
    method.append(0)
    log_method.append(0)
    ld_include.append(1)
    ud_include.append(1)
    index_type.append(0)

Nind = 10
Encoding = 'BG'
FieldD = np.array([len_autosome,
                   the_lb,
                   the_ub,
                   method,
                   log_method,
                   ld_include,
                   ud_include,
                   index_type])


def create_matplotlib(x,y,r,arc_f,arc_b,x1,y1,r1):
    # 创建绘图对象f
    f = plt.figure(num=1, figsize=(7,5), dpi=80, facecolor="pink", edgecolor='green', frameon=True)
    # 创建一副子图
    fig1 = plt.subplot(1, 1, 1)
    units = get_the_route(x,y,r,arc_f,arc_b)
    x = []
    y = []
    for i in units:
        x.append(i.startX)
        y.append(i.startY)
    fig1.plot(x, y, color='red', linewidth=3, linestyle='--')  # 画第一条线
    fig1.grid(which='major', axis='x', color='b', linestyle='-', linewidth=2)  # 设置网格
    f.savefig('test.jpg')


def aim(Phen, canvas,canvas_route):
    new_x1 = Phen[:, 0:3] + t_x1
    new_y1 = Phen[:, 3:6] + t_y1
    new_r1 = Phen[:, 6:9] + t_r1
    new_front = Phen[:, 9:12] + t_front
    new_behind = Phen[:, 12:15] + t_behind
    new_x2 = Phen[:, 15:18] + t_x2
    new_y2 = Phen[:, 18:21] + t_y2
    new_r2 = Phen[:, 21:24] + t_r2
    new_r1 = abs(new_r1)
    new_front = abs(new_front)
    new_behind = abs(new_behind)
    new_r2 = abs(new_r2)
    newPhen = []
    current_array = Phen.astype('int64')
    Best_value = 1.0
    Best_route = None
    global image
    global im
    for i in range(0, len(current_array)):
        # print(new_x1[i], new_y1[i], new_r1[i], new_front[i], new_behind[i], new_x2[i], new_y2[i], new_r2[i])
        temp1 = x1.copy()
        temp2 = y1.copy()
        temp3 = r1.copy()
        temp4 = front.copy()
        temp5 = behind.copy()
        temp6 = x2.copy()
        temp7 = y2.copy()
        temp8 = r2.copy()
        temp1[17] = new_x1[i][0]
        temp1[18] = new_x1[i][1]
        temp1[19] = new_x1[i][2]
        temp2[17] = new_y1[i][0]
        temp2[18] = new_y1[i][1]
        temp2[19] = new_y1[i][2]
        temp3[17] = new_r1[i][0]
        temp3[18] = new_r1[i][1]
        temp3[19] = new_r1[i][2]
        temp4[17] = new_front[i][0]
        temp4[18] = new_front[i][1]
        temp4[19] = new_front[i][2]
        temp5[17] = new_behind[i][0]
        temp5[18] = new_behind[i][1]
        temp5[19] = new_behind[i][2]
        temp6[17] = new_x2[i][0]
        temp6[18] = new_x2[i][1]
        temp6[19] = new_x2[i][2]
        temp7[17] = new_y2[i][0]
        temp7[18] = new_y2[i][1]
        temp7[19] = new_y2[i][2]
        temp8[17] = new_r2[i][0]
        temp8[18] = new_r2[i][1]
        temp8[19] = new_r2[i][2]
        bi.dod.update_curves(temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8)
        create_matplotlib(temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8)
        image = Image.open("test.jpg")
        im = ImageTk.PhotoImage(image)
        canvas_route.create_image(221,160, image = im)
        con = bi.cal_bias(None, -1500, -1450, canvas)
        print(con)
        if float(con[0] / con[1]) < Best_value:
            Best_value = con[0] / con[1]
            Best_route = [temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8]
        newPhen.append([con[0] / con[1]])
    return np.array(newPhen), Best_value, Best_route


def Choose(num, OldChrom, FitnV):  # 选择出的染色体个数
    SelCh = OldChrom[selecting('etour', FitnV, num), :]  # 使用轮盘赌方式选择
    return SelCh


def Mix(OldChrom, pm):
    # np.random.seed(0)
    p = np.array([1 - pm, pm])
    change_index = []
    for i in range(0, 24):
        index = np.random.choice([0, 1], p=p.ravel())
        if index == 1:
            change_index.append(i)
    NewChrom = np.copy(OldChrom)
    for i in change_index:
        NewChrom[0, i * 10:((i + 1) * 10)] = OldChrom[1, i * 10:((i + 1) * 10)]
        NewChrom[1, i * 10:((i + 1) * 10)] = OldChrom[0, i * 10:((i + 1) * 10)]
    return NewChrom


def Change(OldChrom):
    NewChrom = mutbin('BG', OldChrom, FieldD, 0.3)
    return NewChrom


def Mix2(OldChrom, FitnV):  # 交叉
    le = np.shape(OldChrom)
    le = le[0]
    NewChrom = []
    for i in range(0, int(le / 2)):
        SelCh = OldChrom[selecting('rws', FitnV, 2), :]  # 使用轮盘赌方式选择
        SelCh = Mix(SelCh, 0.8)
        SelCh = Change(SelCh)
        if i is 0:
            NewChrom = SelCh
        else:
            NewChrom = np.concatenate([NewChrom, SelCh], axis=0)
    return NewChrom


def run(canvas=None,canvas_route=None,bi_ori=None,bi_now=None,se=None):
    T = 50
    Best = []
    y = []
    x = []
    Chrom = crtpc(Encoding, Nind, FieldD)
    for i in range(0, T):
        print("Round", i)
        The_Phen = bs2ri(Chrom, FieldD)
        ObjV, Best_value, Best_route = aim(The_Phen,canvas,canvas_route)
        print("当前种群", ObjV)
        x.append(i)
        y.append(Best_value)
        bi_now.set("当前最优侵限值："+str(Best_value))
      #  se.update()
        FitnV = ranking(ObjV)
        NewChrom = Mix2(Chrom, FitnV)
        NewChrom = np.vstack([Chrom, NewChrom])  # 得到新一代种群的染色体矩阵
        The_Phen3 = bs2ri(NewChrom, FieldD)
        ObjV3, Best_value3, Best_route = aim(The_Phen3, canvas,canvas_route)
        print("加入新种群后", ObjV3)
        FitnV3 = ranking(ObjV3)
        bestIdx = heapq.nlargest(Nind, range(len(FitnV3)), FitnV3.take)
        Chrom = np.vstack([NewChrom[bestIdx, :]])
